﻿using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace TC.Vacation.Spider.Core.Iocp
{
    public class TcpClient
    {
        private IPEndPoint remoteEndPoint;
        private Socket clientSocket;

        /// <summary>
        /// 初始化Tcp连接
        /// </summary>
        /// <param name="remoteIp">远程服务器IP地址</param>
        /// <param name="port">端口</param>
        public TcpClient(string remoteIp, int port)
        {
            remoteEndPoint = new IPEndPoint(IPAddress.Parse(remoteIp), port);
        }

        /// <summary>
        /// 发送数据
        /// </summary>
        /// <param name="message"></param>
        public void Send(string message)
        {
            try
            {
                clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                clientSocket.Connect(remoteEndPoint);
                var writeEventArgs = new SocketAsyncEventArgs();
                var data = Encoding.UTF8.GetBytes(message);
                writeEventArgs.RemoteEndPoint = remoteEndPoint;
                writeEventArgs.SetBuffer(data, 0, data.Length);
                writeEventArgs.UserToken = clientSocket;
                writeEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(OnComplete);
                clientSocket.SendToAsync(writeEventArgs);
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        /// <summary>
        /// 发送完成后触发
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnComplete(object sender, SocketAsyncEventArgs e)
        {
            if (e.SocketError == SocketError.Success)
            {
                var message = Encoding.UTF8.GetString(e.Buffer, e.Offset, e.BytesTransferred);
            }
            else
            {
                Close(e);
            }
        }

        /// <summary>
        /// 关闭到服务端的连接并释放资源
        /// </summary>
        /// <param name="e"></param>
        public void Close(SocketAsyncEventArgs e)
        {
            var token = e.UserToken as Socket;
            try
            {
                token.Shutdown(SocketShutdown.Send);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                token.Close();
            }
        }
    }
}
